﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.LIB;

namespace YJKDimensionModel.PlaneSlopeDimension
{
	public class SlopeDimensionStructCol
	{
		private Document Doc { get; set; }

		public List<SlopeDimensionStruct> LstSlopeDimensionStruct { get; set; }

		public SlopeDimensionStructCol(Autodesk.Revit.DB.Document doc)
		{
			this.LstSlopeDimensionStruct = new List<SlopeDimensionStruct>();
			this.m_lstFamilyDocNames = new List<string>();
			this.Doc = doc;
		}

		public SlopeDimensionStructCol(ExternalCommandData cmdData)
		{
			this.LstSlopeDimensionStruct = new List<SlopeDimensionStruct>();
			this.m_lstFamilyDocNames = new List<string>();
			this.Doc = cmdData.Application.ActiveUIDocument.Document;
			string versionNumber = cmdData.Application.Application.VersionNumber;
			this.m_familyDocDirectory = this.m_familyDocDirectory + "\\" + versionNumber + "\\SlopeLabel";
		}

		public bool Init()
		{
			if (!this.GetFamilyInGivenDirectory() || this.LstSlopeDimensionStruct == null)
			{
				return false;
			}
			foreach (SlopeDimensionStruct slopeDimStruct in this.LstSlopeDimensionStruct)
			{
				this.InitSlopeDimensionStruct(slopeDimStruct);
			}
			return true;
		}

		private bool InitSlopeDimensionStruct(SlopeDimensionStruct slopeDimStruct)
		{
			Family family = slopeDimStruct.Family;
			Document document = family.Document.EditFamily(family);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			filteredElementCollector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericAnnotation);
			if (filteredElementCollector.Count<Element>() <= 0)
			{
				return false;
			}
			foreach (Element element in filteredElementCollector)
			{
				FamilySymbol familySymbol = element as FamilySymbol;
				if (familySymbol != null)
				{
					family = familySymbol.Family;
					document = family.Document.EditFamily(family);
					filteredElementCollector = new FilteredElementCollector(document);
					filteredElementCollector.OfClass(typeof(TextElement));
					if (filteredElementCollector.Count<Element>() <= 0)
					{
						return false;
					}
					IEnumerator<Element> enumerator2 = filteredElementCollector.GetEnumerator();
					{
						if (enumerator2.MoveNext())
						{
							Element element2 = enumerator2.Current;
							TextElement textElement = element2 as TextElement;
							if (textElement != null)
							{
								TextElementType symbol = textElement.Symbol;
								slopeDimStruct.Font = symbol.get_Parameter(BuiltInParameter.TEXT_FONT).AsString();
								slopeDimStruct.TextHeight = this.FeetToMM(symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble());
								slopeDimStruct.TextWidth = symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
								slopeDimStruct.ArrowAngle = 15.0;
								slopeDimStruct.ArrowLength = 3.0;
								slopeDimStruct.Offset = 1.0;
							}
						}
						break;
					}
				}
			}
			return true;
		}

		private bool LstFamilyDocNamesInit()
		{
			this.m_lstFamilyDocNames.Clear();
			try
			{
				FileStream fileStream = new FileStream(this.m_slopeConfigFilePath, FileMode.Open);
				StreamReader streamReader = new StreamReader(fileStream);
				while (!streamReader.EndOfStream)
				{
					this.m_lstFamilyDocNames.Add(streamReader.ReadLine());
				}
				streamReader.Close();
				fileStream.Close();
			}
			catch (IOException)
			{
				return false;
			}
			return true;
		}

		private bool GetFamilyInGivenDirectory()
		{
			this.LstSlopeDimensionStruct.Clear();
			this.LstFamilyDocNamesInit();
			DirectoryInfo directoryInfo = new DirectoryInfo(this.m_familyDocDirectory);
			FileInfo[] files = directoryInfo.GetFiles("*.rfa");
			using (Transaction transaction = new Transaction(this.Doc))
			{
				try
				{
					transaction.Start("LoadFamily");
					foreach (FileInfo fileInfo in files)
					{
						string text = fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf('.'));
						if (this.m_lstFamilyDocNames.Contains(text))
						{
							this.GetFamilySymbol(text);
						}
					}
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.Commit();
					return false;
				}
			}
			return true;
		}

		private bool GetFamilySymbol(string familyName)
		{
			Family family = null;
			ISet<ElementId> set = null;
			if (!this.IsExistFamilyInDoc(familyName, out family))
			{
				string text = this.m_familyDocDirectory + "\\" + familyName + ".rfa";
				bool flag = this.Doc.LoadFamily(text, out family);
				if (!flag || family == null)
				{
					return false;
				}
				set = family.GetFamilySymbolIds();
				foreach (ElementId elementId in set)
				{
					FamilySymbol familySymbol = this.Doc.GetElement(elementId) as FamilySymbol;
					if (familySymbol != null)
					{
						SlopeDimensionStruct item = new SlopeDimensionStruct(familySymbol, 0.0, 0.0, "仿宋", 0.0, 0.0, 0.0, 8.0, "3%", "");
						this.LstSlopeDimensionStruct.Add(item);
					}
				}
			}
			if (set != null)
			{
				return true;
			}
			set = family.GetFamilySymbolIds();
			foreach (ElementId elementId2 in set)
			{
				FamilySymbol familySymbol = this.Doc.GetElement(elementId2) as FamilySymbol;
				if (familySymbol != null)
				{
					SlopeDimensionStruct item2 = new SlopeDimensionStruct(familySymbol, 0.0, 0.0, "仿宋", 0.0, 0.0, 0.0, 8.0, "3%", "");
					this.LstSlopeDimensionStruct.Add(item2);
				}
			}
			return true;
		}

		private bool IsExistFamilyInDoc(string familyName, out Family family)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.Doc);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(Family));
			IList<Element> list = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
			foreach (Element element in list)
			{
				Family family2 = element as Family;
				if (family2 != null && family2.Name == familyName)
				{
					family = family2;
					return true;
				}
			}
			family = null;
			return false;
		}

		private double FeetToMM(double feet)
		{
			return feet * 304.8;
		}

		private string m_familyDocDirectory = Product.FamilyLocation;

		private string m_slopeConfigFilePath = Product.DataLocation + "\\SlopeMark.txt";

		private List<string> m_lstFamilyDocNames;
	}
}
